package category

import (
	"cgs-server/server/base"
	"cgs-server/server/model"
	"errors"
	"go.mongodb.org/mongo-driver/bson"
)

type CategroyService interface {
	ListAll(visualType string, user *model.User) ([]*Vo, error)
	//Init() error

	ListPage(mdl *model.DataUserModel) (*model.PageResult, error)

	base.Service
}

func NewCategoryService() CategroyService {
	categoryRepository := NewCategoryRepository()
	return &categoryService{
		catergoryRepo: categoryRepository,
		ServiceImpl: base.ServiceImpl{
			Repo: categoryRepository,
		},
	}
}

type categoryService struct {
	catergoryRepo CategoryRepository
	base.ServiceImpl
}

func (c *categoryService) Init(...string) error {
	return c.catergoryRepo.InitDB()
}

func (c *categoryService) ListAll(visualType string, user *model.User) ([]*Vo, error) {
	/*if user == nil {
		return nil, errors.New("Permission denied.")
	}*/
	if visualType == "" {
		return nil, errors.New("VisualType is required.")
	}

	err := c.AddDefaultCategory(Category{VisualType: visualType}, user)
	if err != nil {
		return nil, err
	}

	return c.catergoryRepo.FindAll(visualType, user)
}

// 添加分类
func (c *categoryService) Save(mdl *model.DataUserModel) error {
	if _, ok := mdl.Data.(*Category); ok {
		// 模块值唯一
		res, err := c.catergoryRepo.FindByCategoryValue(mdl)
		if err != nil {
			return err
		}
		if res != nil {
			return errors.New("模块值需要唯一!")
		}
		err = c.catergoryRepo.Insert(mdl)
		return err
	} else {
		return errors.New("Category type error")
	}
}

func (c *categoryService) GetOne(mdl *model.DataUserModel) (interface{}, error) {
	return c.catergoryRepo.FindOne(mdl)
}

func (c *categoryService) Update(mdl *model.DataUserModel) error {
	return c.catergoryRepo.Update(mdl)
}

func (c *categoryService) Remove(mdl *model.DataUserModel) error {
	return c.catergoryRepo.Delete(mdl)
}

func (c *categoryService) Count(mdl *model.DataUserModel) int64 {
	category, ok := mdl.Data.(*Category)
	if !ok {
		return 0
	}

	mdl.Filter = &bson.M{
		"VisualType": category.VisualType,
		"tenantId":   mdl.User.TenantId,
	}
	count, _ := c.catergoryRepo.Count(mdl)
	return count
}

func (c *categoryService) AddDefaultCategory(category Category, user *model.User) error {
	// check default category: value=-1
	if category.VisualType == "Org" { // 组织分类
		return nil
	}

	ca := &Category{
		CategoryValue: "-1",
		VisualType:    category.VisualType,
		CategoryKey:   "默认",
	}
	value, _ := c.catergoryRepo.FindByCategoryValue(&model.DataUserModel{
		Data: ca,
		User: user,
	})
	if value != nil {
		return nil
	}

	// 没找到新增一个
	err := c.catergoryRepo.Insert(&model.DataUserModel{
		Data: ca,
		User: user,
	})

	return err
}

func (c *categoryService) ListPage(mdl *model.DataUserModel) (*model.PageResult, error) {
	category, ok := mdl.Data.(*Category)
	if !ok {
		return nil, model.NewTypeError("category")
	}

	err := c.AddDefaultCategory(*category, mdl.User)
	if err != nil {
		return nil, err
	}

	mdl.ResolvePageOption()
	mdl.Filter = &bson.M{
		"VisualType": category.VisualType,
		"tenantId":   mdl.User.TenantId,
	}
	categoryList, err := c.catergoryRepo.Find(mdl)
	if err != nil {
		return nil, err
	}
	count, _ := c.catergoryRepo.Count(mdl)

	result := model.PageResult{
		Records: categoryList,
		Total:   count,
		Size:    mdl.Page.Size,
	}

	return &result, nil
}
